Skip to content

Partial fix: strip required from anyOf/oneOf schema items to reduce TS2615 circular reference errors#3694

Draft
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-circular-reference-error
Draft

Partial fix: strip required from anyOf/oneOf schema items to reduce TS2615 circular reference errors#3694
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-circular-reference-error

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 30, 2026

Schemas with circular anyOf/oneOf references (e.g. a FilterGroup that contains anyOf: [FilterGroup, SoloFilter]) cause TypeScript error TS2615 ("Type of property X circularly references itself in mapped type") when json-schema-to-ts's ParseObjectSchema maps over required fields whose types involve the circular schema.

Changes

  • packages/fets/src/client/types.ts: Added FixAnyOfOneOfRequiredFields transformation to FixJSONSchema pipeline. Uses the same HotScript Call<Tuples.Map<Objects.Omit<'required'>>, T['anyOf']> pattern as the existing FixAdditionalPropertiesForAllOf to strip required from items inside anyOf/oneOf arrays. This prevents the circular required-fields mapped type check in ts-algebra's _$Object from triggering TS2615 for inner schemas.

  • packages/fets/tests/client/fixtures/example-anyof-circular-ref-oas.ts: Test fixture reproducing the reported OAS spec with a self-referencing FilterGroup schema.

  • packages/fets/tests/client/anyof-circular-ref-test.ts: Test file documenting the issue.

Known limitation

This is a partial fix. Stripping required from anyOf/oneOf items prevents TS2615 in inner schemas, but TS2615 still occurs when the outer component schema (e.g. FilterGroup in components/schemas) has required fields that include the circular property. The cycle in json-schema-to-ts's ParseAnyOfSchemaMergeSubSchema path creates intermediate types that TypeScript cannot recognize as safe deferred recursion, even with required stripped.

The complete fix requires keeping $ref stubs (unexpanded) for anyOf/oneOf items in ResolveRefsInObj and passing the full normalized OAS as rootSchema to FromSchema calls, so that ParseReferenceSchema handles the cycle lazily instead of ParseAnyOfSchema.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.clickhouse.cloud
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/feTS/feTS/node_modules/.bin/ts-node scripts/download-oas.ts (dns block)
  • api.navitia.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/feTS/feTS/node_modules/.bin/ts-node scripts/download-oas.ts (dns block)
  • api.pulumi.com
    • Triggering command: /usr/local/bin/pulumi pulumi plugin install resource aws v5.43.0 (dns block)
    • Triggering command: /usr/local/bin/pulumi pulumi plugin install resource docker v3.6.1 (dns block)
    • Triggering command: /usr/local/bin/pulumi pulumi plugin install resource cloudflare v4.16.0 (dns block)
  • developer.spotify.com
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/feTS/feTS/node_modules/.bin/ts-node scripts/download-oas.ts (dns block)
  • scarf.sh
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node ./report.js (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.

Copilot AI linked an issue Mar 30, 2026 that may be closed by this pull request
Copilot AI and others added 2 commits March 30, 2026 07:37
…duce TS2615 circular reference errors

Agent-Logs-Url: https://github.com/ardatan/feTS/sessions/c2d8eec9-96bd-4af6-a1c7-65ddf2986403

Co-authored-by: ardatan <20847995+ardatan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix circular reference error in OpenAPI spec Partial fix: strip required from anyOf/oneOf schema items to reduce TS2615 circular reference errors Mar 30, 2026
Copilot AI requested a review from ardatan March 30, 2026 08:06
@github-actions
Copy link
Copy Markdown
Contributor

💻 Website Preview

The latest changes are available as preview in: https://3e60071d.fets.pages.dev

@github-actions
Copy link
Copy Markdown
Contributor

✅ Benchmark Results

     ✓ no_errors{server:node-http,mode:no-schema}
     ✓ expected_result{server:node-http,mode:no-schema}
     ✓ no_errors{server:node-http,mode:json-schema}
     ✓ expected_result{server:node-http,mode:json-schema}
     ✓ no_errors{server:uWebSockets,mode:no-schema}
     ✓ expected_result{server:uWebSockets,mode:no-schema}
     ✓ no_errors{server:uWebSockets,mode:json-schema}
     ✓ expected_result{server:uWebSockets,mode:json-schema}

     checks......................................: 100.00% ✓ 971066      ✗ 0     
     data_received...............................: 88 MB   735 kB/s
     data_sent...................................: 62 MB   514 kB/s
     http_req_blocked............................: avg=1.45µs   min=681ns    med=1.21µs   max=1.13ms   p(90)=1.9µs    p(95)=2.82µs  
     http_req_connecting.........................: avg=1ns      min=0s       med=0s       max=157.22µs p(90)=0s       p(95)=0s      
     http_req_duration...........................: avg=169.46µs min=89.13µs  med=159.45µs max=14.74ms  p(90)=189.92µs p(95)=201.38µs
       { expected_response:true }................: avg=169.46µs min=89.13µs  med=159.45µs max=14.74ms  p(90)=189.92µs p(95)=201.38µs
     ✓ { server:node-http,mode:json-schema }.....: avg=179.66µs min=113.03µs med=169.59µs max=11.66ms  p(90)=198.27µs p(95)=208.89µs
     ✓ { server:node-http,mode:no-schema }.......: avg=171.85µs min=103.36µs med=159.19µs max=14.74ms  p(90)=190.01µs p(95)=203.73µs
     ✓ { server:uWebSockets,mode:json-schema }...: avg=166.67µs min=92.82µs  med=157.89µs max=12.14ms  p(90)=186.35µs p(95)=196.17µs
     ✓ { server:uWebSockets,mode:no-schema }.....: avg=160.45µs min=89.13µs  med=151.01µs max=14.39ms  p(90)=180.31µs p(95)=191.21µs
     http_req_failed.............................: 0.00%   ✓ 0           ✗ 485533
     http_req_receiving..........................: avg=23µs     min=8.34µs   med=21.26µs  max=3.14ms   p(90)=31.49µs  p(95)=35.23µs 
     http_req_sending............................: avg=8.03µs   min=4.02µs   med=7.19µs   max=2.03ms   p(90)=11.8µs   p(95)=13.84µs 
     http_req_tls_handshaking....................: avg=0s       min=0s       med=0s       max=0s       p(90)=0s       p(95)=0s      
     http_req_waiting............................: avg=138.42µs min=66.5µs   med=128.5µs  max=14.67ms  p(90)=156.08µs p(95)=166.18µs
     http_reqs...................................: 485533  4046.039387/s
     iteration_duration..........................: avg=242.5µs  min=145.88µs med=231.06µs max=14.9ms   p(90)=267.53µs p(95)=282.95µs
     iterations..................................: 485533  4046.039387/s
     vus.........................................: 1       min=1         max=1   
     vus_max.....................................: 2       min=2         max=2   

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Circular reference error in openapi spec

2 participants